package com.lx.aop;

import com.lx.annotation.MyCache;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import java.util.concurrent.TimeUnit;

/**
 * 雒鑫
 */
@Component
@Aspect
public class MyCacheAop {
    /**
     * 定义切点
     *
     * @param myCache
     */
    @Pointcut("@annotation(myCache)")
    public void point(MyCache myCache) {
    }

    @Autowired
    private RedisTemplate redisTemplate;

    /**
     * 环绕通知
     *
     * @param joinPoint
     * @param myCache
     * @return
     */
    @Around("point(myCache)")
    public Object Around(ProceedingJoinPoint joinPoint, MyCache myCache) {
        String s = myCache.cacheName();
        String key = myCache.key();
        int time = myCache.time();
        /**
         * 思路：
         * 1.拼接redis中缓存存放的key值
         * 若redis中是否存在该key
         * 如果存在，则直接取出来返回即可，不需要执行目标方法
         * 如果不存在 就执行目标方法 然后将缓存放一份到redis当中
         */
        Object data;
        String redisKey = new StringBuilder(s).append(":").append(key).toString();
        data = redisTemplate.opsForValue().get(redisKey);
        if (data != null) {
            System.out.println("从redis当中取数据");
            return data;
        }
        try {
            //执行目标方法(相当于取执行controller当中的方法直接去查数据库)
            data = joinPoint.proceed();
            //接口返回的结果存放一份到redis当中
            redisTemplate.opsForValue().set(redisKey, data, time, TimeUnit.SECONDS);
        } catch (Throwable e) {
            throw new RuntimeException(e);
        }
        return data;
    }
}
